package com.yqb.study.common.rest;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.yqb.study.common.vo.ResultVo;
import com.yqb.study.util.ToolUtil;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class RestClient {

	@Autowired
	private RestTemplate restTemplate;

	// 调用get方式接口,传参数是拼接在url后面
	private String urlAddParas(String url, Map<String, Object> requestPara) {
		
		if (ToolUtil.isOneEmpty(url, requestPara)) {
			return url;
		}
		
		Boolean flag = true;
		for (Map.Entry<String, Object> paraItem : requestPara.entrySet()) {
			if (flag) {
				url = url + "?" + paraItem.getKey() + "=" + paraItem.getValue().toString();
				flag = false;
			} else {
				url = url + "&" + paraItem.getKey() + "=" + paraItem.getValue().toString();
			}
		}		
		
		return url;
	}
	
	// 将传入Map参数转成LinkedMultiValueMap存入POST表单中发到服务端
	private LinkedMultiValueMap<String, String> Map2LinkedMultiValueMap(Map<String, Object> requestPara) {
		LinkedMultiValueMap<String, String> para = new LinkedMultiValueMap<>();

		for (Map.Entry<String, Object> paraItem : requestPara.entrySet()) {
			para.add(paraItem.getKey(), paraItem.getValue().toString());
		}

		return para;
	}

	// ---------------------- 默认GET ----------------------
	public <T> ResultVo<T> request(String url) {

		return requestGet(url);
	}

	public <T> ResultVo<T> request(String url, Map<String, Object> requestPara) {
		return requestGet(url, requestPara);
	}
	// ---------------------- 默认GET ----------------------

	// ---------------------- GET ----------------------
	public <T> ResultVo<T> requestGet(String url) {

		ResultVo<T> resultVo = null;

		if (StringUtils.isEmpty(url)) {
			return resultVo;
		}

		try {
			resultVo = restTemplate.getForObject(url, ResultVo.class);
		} catch (Exception e) {
			// 可能网址错误
			log.error(e.getMessage(), e);
		}

		return resultVo;
	}

	public <T> ResultVo<T> requestGet(String url, Map<String, Object> requestPara) {
		ResultVo<T> resultVo = null;

		if (StringUtils.isEmpty(url)) {
			return resultVo;
		}

		try {
			url = urlAddParas(url, requestPara);
			// 执行HTTP请求
			ResponseEntity<ResultVo> response = restTemplate.exchange(url, HttpMethod.GET, null, ResultVo.class);

			resultVo = response.getBody();
		} catch (Exception e) {
			// 可能网址错误
			log.error(e.getMessage(), e);
		}

		return resultVo;
	}
	// ---------------------- GET ----------------------

	// ---------------------- POST ----------------------
	public <T> ResultVo<T> requestPost(String url) {

		ResultVo<T> resultVo = null;

		if (StringUtils.isEmpty(url)) {
			return resultVo;
		}

		try {
			resultVo = restTemplate.postForObject(url, null, ResultVo.class);
		} catch (Exception e) {
			// 可能网址错误
			log.error(e.getMessage(), e);
		}

		return resultVo;
	}

	public <T> ResultVo<T> requestPost(String url, Map<String, Object> requestPara) {
		ResultVo<T> resultVo = null;

		if (StringUtils.isEmpty(url)) {
			return resultVo;
		}

		try {
			HttpHeaders headers = new HttpHeaders();
			// 请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
			// 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
			// 也支持中文
			MultiValueMap<String, String> params = Map2LinkedMultiValueMap(requestPara);
			HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
			// 执行HTTP请求
			ResponseEntity<ResultVo> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, ResultVo.class);

			resultVo = response.getBody();
		} catch (Exception e) {
			// 可能网址错误
			log.error(e.getMessage(), e);
		}

		return resultVo;
	}
	// ---------------------- POST ----------------------
}
